namespace Org.Loon.Framework.Xna.Game.Action.Scripting.Pack
{

    using Org.Loon.Framework.Xna.Game.Core;
    using Org.Loon.Framework.Xna.Game.Core.Graphics;
    using Org.Loon.Framework.Xna.Game.Core.Timer;
    using Org.Loon.Framework.Xna.Game.Core.Geom;
    using Org.Loon.Framework.Xna.Game.Utils;
    using Org.Loon.Framework.Xna.Game.Core.Graphics.OpenGL;

    public interface DirectionListener
    {

        void update(PackSprite spr, int direction);

    }

    public class PackSprite : LObject
    {


        private DirectionListener listener;

        private int direction;

        private PackAnimation animation;

        internal bool visible = true;

        private int frame;

        private float width, height;

        private float subX, subY, subWidth, subHeight;

        private LColor color;

        private LTimer timer;

        public PackSprite(PackAnimation a)
        {
            SetAnimation(a);
        }

        public void Sub(float x, float y, float w, float h)
        {
            this.subX = x;
            this.subY = y;
            this.subWidth = w;
            this.subHeight = h;
        }

        public void SetSize(float w, float h)
        {
            this.width = w;
            this.height = h;
        }

        public void SetFrame(int frame)
        {
            this.frame = frame;
        }

        public int GetFrame()
        {
            return frame;
        }

        protected void NextFrame()
        {
            frame++;
        }

        protected void PrevFrame()
        {
            frame--;
        }

        protected void Reset()
        {
            frame = 0;
        }

        public override int GetWidth()
        {
            return (width == 0 ? animation.GetFrame(frame).GetWidth() : (int)width);
        }

        public override int GetHeight()
        {
            return (height == 0 ? animation.GetFrame(frame).GetHeight()
                    : (int)height);
        }

        public RectBox GetCollisionBox()
        {
            return GetRect(X(), Y(), GetWidth(), GetHeight());
        }

        public int GetLeft()
        {
            return MathUtils.Round(GetX());
        }

        public int GetTop()
        {
            return MathUtils.Round(GetY());
        }

        public bool CollidesWith(PackSprite s)
        {
            return ((GetLeft() < (s.GetLeft() + s.GetWidth()))
                    && ((GetLeft() + GetWidth()) > s.GetLeft())
                    && (GetTop() < (s.GetTop() + s.GetHeight())) && ((GetTop() + GetHeight()) > s
                    .GetTop()));
        }

        public void SetDelay(long d)
        {
            timer.SetDelay(d);
        }

        public long GetDelay()
        {
            return timer.GetDelay();
        }

        public void SetAnimation(PackAnimation animation)
        {
            this.animation = animation;
            if (timer == null)
            {
                this.timer = new LTimer(150);
            }
            this.visible = true;
        }

        public void Draw(LTexturePack pack, PackView view)
        {
            PackFrame o = animation.GetFrame(frame);
            float rx = view.WorldToRealX(GetX());
            float ry = view.WorldToRealY(GetY());
            if (o.flag)
            {
                if (subWidth == 0 && subHeight == 0 && width != 0 && height != 0)
                {
                    pack.Draw(o.id, rx, ry, width, height, rotation, color);
                }
                else if (subX != 0 || subY != 0 || subWidth != 0
                      || subHeight != 0)
                {
                    pack.Draw(o.id, rx, ry, width, height, subX, subY, subWidth,
                            subHeight, rotation, color);
                }
                else
                {
                    pack.Draw(o.id, rx, ry, rotation, color);
                }
            }
            else
            {
                if (subWidth == 0 && subHeight == 0 && width != 0 && height != 0)
                {
                    pack.Draw(o.name, rx, ry, width, height, rotation, color);
                }
                else if (subX != 0 || subY != 0 || subWidth != 0
                      || subHeight != 0)
                {
                    pack.Draw(o.name, rx, ry, width, height, subX, subY, subWidth,
                            subHeight, rotation, color);
                }
                else
                {
                    pack.Draw(o.name, rx, ry, rotation, color);
                }
            }
        }

        public override void Update(long elapsedTime)
        {
            if (timer.Action(elapsedTime))
            {
                NextFrame();
            }
        }

        public float GetUWidth()
        {
            return width;
        }

        public float GetUHeight()
        {
            return height;
        }

        public float GetSubHeight()
        {
            return subHeight;
        }

        public float GetSubWidth()
        {
            return subWidth;
        }

        public float GetSubX()
        {
            return subX;
        }

        public float GetSubY()
        {
            return subY;
        }

        public LColor GetColor()
        {
            return color;
        }

        public void SetColor(LColor color)
        {
            this.color = color;
        }

        public override float GetRotation()
        {
            return rotation;
        }

        public override void SetRotation(float rotation)
        {
            this.rotation = rotation;
        }

        public bool IsVisible()
        {
            return visible;
        }

        public void SetVisible(bool visible)
        {
            this.visible = visible;
        }

        public int GetDirection()
        {
            return direction;
        }

        public void SetDirection(int d)
        {
            this.direction = d;
            if (listener != null)
            {
                listener.update(this, d);
            }
        }

        public DirectionListener GetDirectionListener()
        {
            return listener;
        }

        public void SetDirectionListener(DirectionListener listener)
        {
            this.listener = listener;
        }

    }
}
